<?php

namespace app\common\controller;

use think\Cache;
use think\Controller;
use think\Db;
use think\Config;
use app\common\error\CodeConfig as errorBn;
use think\Request;
use app\common\mysql\User as userMysql;
use app\common\business\User as userBn;
use app\common\letterbusiness\User as letteruserBn;
use app\common\timebusiness\User as timeuserBn;
class HomeBase extends Controller {

    /**
     * 架构函数
     * @param Request $request Request对象
     * @access public
     */
    public function __construct() {
        try {

            if (Config('app_sign')) {
                // $this->apiVerify();
            }
        } catch (\Exception $e) {
            $this->_echoErrorMessage($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 输出错误的信息
     * 
     * @param string $message
     * @param int $errno 错误编号
     */
    protected function _echoErrorMessage($message = '', $errno = 1, $duiba = 0, $data = array()) {

        if (in_array($errno, array(10501))) {
            //    $message = "system bug";
        }
//        $codeConfig = errorBn::getCodeConfig();
//        if (isset($codeConfig[$errno])) {
//            $message = $codeConfig[$errno];
//        }


        if ($duiba == 0) {
            $return = array(
                'errno' => trim($errno),
                'errmsg' => $message,
            );
        } else {
            $return = array(
                'status' => 'fail',
                'errorMessage' => $message,
                'credits' => $data['credits']
            );
        }

        $callback = input('callback');
        if ($callback) {
            $this->_displayJsonp($return);
        } else {
            $this->_displayJson($return);
        }
    }

    /**
     * 请求时输出成功的信息,并退出
     * 
     * @param string $message
     * @param array $data
     */
    protected function _echoSuccessMessage($message, $data = array(), $duiba = 0) {
        if ($duiba == 0) {
            $return = array(
                'errno' => '200',
                'errmsg' => $message,
                'data' => $data
            );
        } else {
            $return = array(
                'status' => 'ok',
                'errorMessage' => '',
                'bizId' => $data['orderNum'],
                'credits' => $data['credits']
            );
        }
        $callback = input('callback');
        if ($callback) {
            $this->_displayJsonp($return);
        } else {
            $this->_displayJson($return);
        }
    }

    /**
     * 请求时输出成功的信息,并退出
     *
     * @param string $message
     * @param array $data
     */
    protected function _echoDuibaMessage() {
        echo 'ok';
    }

    /**
     * 输出json格式的数据
     * 
     * @param mixed $data
     */
    public function _displayJson($data) {
        header('Content-type: text/plain; charset=utf-8');
        header('Access-Control-Allow-Origin:*');
        header('Access-Control-Allow-Methods:GET, POST, PUT');
        header('Access-Control-Allow-Headers:x-requested-with,content-type');
        echo json_encode($data, JSON_UNESCAPED_UNICODE);
        exit;
    }

    /* jsonp
     * 格式返回数据
     * 关联用户Session
     * 仅get方式返回数据
     * 无法传输长数据
     */

    function _displayJsonp($datas) {
        header('Content-type: text/plain; charset=utf-8');
        header('Access-Control-Allow-Origin:*');

        echo input('callback') . '(' . json_encode($datas, JSON_UNESCAPED_UNICODE) . ')';
    }

    /**
     * 获取登录cookie
     * 
     * @return string
     */
    public function _getSso() {
        $sso = $this->getCookie("sso");
        if (!$sso) {
            $sso = input('sso', '');
            if (!$sso) {
                $sso = empty($_REQUEST["sso"]) ? "" : $_REQUEST["sso"];
            }
        }
        if (strlen($sso) <= 10) {
            $sso = "";
        }

        return $sso;
    }

    public function is_base64($str) {
        if ($str == base64_encode(base64_decode($str))) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取cookie的值
     * 
     * @param string $key
     * @param mix $default
     */
    public function getCookie($key, $default = "") {       
        if (isset($_REQUEST[$key]) && $key == 'sso') {
            if ($this->is_base64($_REQUEST[$key])) {
                $_REQUEST[$key] = base64_decode($_REQUEST[$key]);
            }
        }
        if (isset($_REQUEST[$key])) {

            return $_REQUEST[$key];
        }
        if (isset($_COOKIE[$key]) && strlen($_COOKIE[$key]) > 0)
            if (isset($_COOKIE[$key]) && $key == 'sso') {
                if ($this->is_base64($_COOKIE[$key])) {
                    $_COOKIE[$key] = base64_decode($_COOKIE[$key]);
                }
            }
        return $_COOKIE[$key];
        return $default;
    }

    /**
     * 校验是否登录,有登陆返回用户ID，没登陆返回0
     *
     * @return type
     * @throws \Exception
     */
    public function _isLoginWeixin() {
        $sso = $this->_getSso();
        if (!$sso) {
            header('Location:/index/querylogin/login/type/weixin');
            exit;
        }

        $memberId = \app\common\business\User::decodeSso($sso);

        if (!$memberId) {
            if (isset($_SESSION)) {
                unset($_SESSION);
            }
            setcookie('sso', "", time(), "/", ".qiu7.net");
            return 0;
        }
        $member = $member = userBn::userInfo($memberId);
        if (!$member) {
            return 0;
        }
        userBn::userlogincount($memberId);
        return $member;
    }

    /**
     * 校验是否登录,有登陆返回用户ID，没登陆返回0
     *
     * @return type
     * @throws \Exception
     */
    public function _isAuthWeixin() {
        if (!isset($_COOKIE['wxauthinfo']) || empty($_COOKIE['wxauthinfo'])) {

            $http_referer = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
            $http_referer = base64_encode($http_referer);
            header('Location:/index/querylogin/authweb/type/weixin/http_referer/' . $http_referer);
            exit;
        }
    }

    /**
     * 校验是否登录
     * 
     * @return int 登录的会员编号
     * @throws \Exception
     */
    public function _validLogin() {
        $sso = $this->_getSso();

        if (empty($sso)) {
            exception('请先登录', 110013);
        } 
        //这里要解析获取用户编号 
        $memberId = \app\common\business\User::decodeSso($sso);
       
        if (!$memberId) {
            exception('用户不存在', 110012);
        }
        $member = userBn::userInfo($memberId);
        if (!$member) {
            exception('用户不存在', 110012);
        }
        // userBn::userlogincount($memberId);

        return $memberId;
    }

    /**
     * 信封校验是否登录
     *
     * @return int 登录的会员编号
     * @throws \Exception
     */
    public function _validLetterLogin() {
        $sso = $this->_getSso();

        if (empty($sso)) {
            exception('请先登录', 110013);
        }

        //这里要解析获取用户编号

        $memberId = \app\common\letterbusiness\User::decodeSso($sso);
        if (!$memberId) {
            exception('用户不存在', 110012);
        }
        $member = letteruserBn::userInfo($memberId);
        if (!$member) {
            exception('用户不存在', 110012);
        }

        return $memberId;
    }
    /**
     * 信封校验是否登录
     *
     * @return int 登录的会员编号
     * @throws \Exception
     */
    public function _validTimeLogin() {
        $sso = input('sso', '');

        if (empty($sso)) {
            exception('请先登录', 110013);
        }

        //这里要解析获取用户编号

        $memberId = \app\common\timebusiness\User::decodeSso($sso);
        if (!$memberId) {
            exception('用户不存在', 110012);
        }
        $member = timeuserBn::userInfo($memberId);
        if (!$member) {
            exception('用户不存在', 110012);
        }

        return $memberId;
    }
    /**
     * 校验是否登录
     * 
     * @return int 登录的会员编号
     * @throws \Exception
     */
    public function _validLogininfo() {
        $sso = $this->_getSso();

        if (empty($sso)) {
            exception('请先登录', 110013);
        }
       
        //这里要解析获取用户编号
        
        $memberId =  \app\common\business\User::decodeSso($sso);
     
        if (!$memberId) {
            exception('用户不存在', 110012);
        }
        $member = $member = userBn::userInfo($memberId);
        if (!$member) {
            exception('用户不存在', 110012);
        }
        //  userBn::userlogincount($memberId);
        return $member;
    }

    /**
     * 校验是否登录,有登陆返回用户ID，没登陆返回0
     * 
     * @return type
     * @throws \Exception
     */
    public function _isLogin() {

        $sso = $this->_getSso();

        if (!$sso) {
            return 0;
        } 
        $memberId = \app\common\business\User::decodeSso($sso);
        if (!$memberId) {
            return 0;
        }
        $member = $member = userBn::userInfo($memberId);
        if (!$member) {
            return 0;
        }
        //  userBn::userlogincount($memberId);
        return $memberId;
    }

    /**
     * 校验是否登录,有登陆返回用户ID，没登陆返回0
     *
     * @return type
     * @throws \Exception
     */
    public function _istimeLogin() {

        $sso = input('sso', '');

        if (!$sso) {
            return 0;
        }
        $memberId = \app\common\timebusiness\User::decodeSso($sso);
        if (!$memberId) {
            return 0;
        }
        $member = $member = timeuserBn::userInfo($memberId);

        if (!$member) {
            return 0;
        }
        //  userBn::userlogincount($memberId);
        return $memberId;
    }
    /**
     * 校验是否登录,有登陆返回用户ID，没登陆返回0
     * 
     * @return type
     * @throws \Exception
     */
    public function _isLogininfo() {
        $sso = $this->_getSso();
        if (!$sso) {
            
        }
        $memberId = \app\common\business\User::decodeSso($sso);
        if (!$memberId) {
            return 0;
        }
        $member = userBn::userInfo($memberId);
        if (!$member) {
            return 0;
        }
        userBn::userlogincount($memberId);
        return $member;
    }

    /**
     * 当前用户是否登录并检验是否被需求禁用
     * 
     * @return type
     * @throws \Exception
     */
    public function _checkIsDisable() {
        $sso = $this->_getSso();
        if (empty($sso)) {
            exception('请先登录', 110013);
        }

        //这里要解析获取用户编号

        $memberId = \app\common\business\User::decodeSso($sso);
        if (!$memberId) {
            exception('用户不存在', 110012);
        }
        $member = $member = userBn::userInfo($memberId);
        if (!$member) {
            exception('用户不存在', 110012);
        }
        if ($member["status"] == 20) {
            exception('您暂时不能发表评论哦~', 110019);
        }
        return $memberId;
    }

    /**
     * 接口安全加密验证数据
     * 
     * @throws \Exception
     */
    public function apiVerify() {
        $params = $this->_getParams();
        if (isset($params['devtest'])) {
            return true;
        }
        //不加密码接口
        $nosecret = Config::get('api_no_secret');
        if ($nosecret) {
            $request = Request::instance();
            $actionurl = strtolower($request->controller() . "/" . $request->action());
            if (in_array($actionurl, $nosecret)) {
                return true;
            }
        }

        if (!isset($_SERVER['HTTP_SIGN']) || empty($_SERVER['HTTP_SIGN'])) {
            exception('连接失败，请升级版本或联系客服sign', 10000222);
        }
        if (!isset($_SERVER['HTTP_KEYTIME']) || empty($_SERVER['HTTP_KEYTIME'])) {
            exception('连接失败，请升级版本或联系客服time', 10000222);
        }
        $sign = $_SERVER['HTTP_SIGN'];
        $headerdata['key_time'] = $_SERVER['HTTP_KEYTIME'];
        $verifyData = $this->createVerifyData($params, $headerdata);

        if (!$this->verify($verifyData, $sign)) {
            exception('连接失败，请升级版本或者联系客服check', 10000222);
        }
    }

    /**
     * 获取所有param
     */
    protected function _getParams() {
        $params = input();
        return $params;
    }

    /**
     * sha256验签
     * 
     * @param type $data
     * @param type $sign
     * @return type
     */
    public function verify($data, $sign) {
        return hash('sha256', $data) === $sign ? true : false;
    }

    /**
     * 除去数组中的空值和签名参数
     * 
     * @param type $para 签名参数组
     * @return type 去掉空值与签名参数后的新签名参数组
     */
    public function paraFilter($para) {
        $para_filter = array();
        while (list ($key, $val) = each($para)) {
            if ($key == "sign" || $key == "sso" || $val == "") {
                continue;
            } else {
                $para_filter[$key] = $para[$key];
            }
        }
        return $para_filter;
    }

    /**
     * 对数组排序
     * 
     * @param type $para 排序前的数组
     * @return type 排序后的数组
     */
    public function argSort($para) {
        ksort($para);
        reset($para);
        return $para;
    }

    /**
     * 创建校验数据
     * 
     * @param type $post
     * @return type
     */
    public function createVerifyData($post, $headerdata) {
        if (empty($post)) {
            $para_sort = array();
        } else {
            //除去待签名参数数组中的空值和签名参数
            $para_filter = $this->paraFilter($post);

            //对待签名参数数组排序
            $para_sort = $this->argSort($para_filter);
        }
        //配置KEY        
        $para_sort['key_time'] = $headerdata['key_time'];
        $para_sort['key'] = Config('api_sign_key');
        //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        $prestr = $this->createLinkstring($para_sort);
        return $prestr;
    }

    /**
     * 把数组所有元素，按照“参数值”的模式用“&”字符拼接成字符串,参数值不带引号
     * 
     * @param type $para 需要拼接的数组
     * @return type 拼接完成以后的字符串
     */
    public function createLinkstring2($para) {
        $arg = "";
        while (list ($key, $val) = each($para)) {
            $arg.=$key . "=" . $val . "&";
            // $arg.=$val . "&";
        }
        //去掉最后一个&字符
        $arg = substr($arg, 0, count($arg) - 2);

        //如果存在转义字符，那么去掉转义
        if (get_magic_quotes_gpc()) {
            $arg = stripslashes($arg);
        }

        return $arg;
    }

    /**
     * 把数组所有元素，按照“参数值”的模式用“&”字符拼接成字符串,参数值不带引号
     * 
     * @param type $para 需要拼接的数组
     * @return type 拼接完成以后的字符串
     */
    public function createLinkstring($para) {
        $arg = "";
        while (list ($key, $val) = each($para)) {
            //$arg.=$key . "=" . $val . "&";
            $arg.=$val . "&";
        }
        //去掉最后一个&字符
        $arg = substr($arg, 0, count($arg) - 2);

        //如果存在转义字符，那么去掉转义
        if (get_magic_quotes_gpc()) {
            $arg = stripslashes($arg);
        }

        return $arg;
    }

    /**
     * $str Unicode编码后的字符串
     * $decoding 原始字符串的编码，默认utf-8
     * $prefix 编码字符串的前缀，默认"&#"
     * $postfix 编码字符串的后缀，默认";"
     */
    public function unicode_decode($unistr, $encoding = 'utf-8', $prefix = '&#', $postfix = ';') {
        $arruni = explode($prefix, $unistr);
        $unistr = '';
        for ($i = 1, $len = count($arruni); $i < $len; $i++) {
            if (strlen($postfix) > 0) {
                $arruni[$i] = substr($arruni[$i], 0, strlen($arruni[$i]) - strlen($postfix));
            }
            $temp = intval($arruni[$i]);
            $unistr .= ($temp < 256) ? chr(0) . chr($temp) : chr($temp / 256) . chr($temp % 256);
        }
        return iconv('UCS-2', $encoding, $unistr);
    }

    /**
     * $str 原始中文字符串
     * $encoding 原始字符串的编码，默认utf-8
     * $prefix 编码后的前缀，默认"&#"
     * $postfix 编码后的后缀，默认";"
     */
    public function unicode_encode($str, $encoding = 'utf-8', $prefix = '&#', $postfix = ';') {
        //将字符串拆分
        $str = iconv("UTF-8", "gb2312", $str);
        $cind = 0;
        $arr_cont = array();

        for ($i = 0; $i < strlen($str); $i++) {
            if (strlen(substr($str, $cind, 1)) > 0) {
                if (ord(substr($str, $cind, 1)) < 0xA1) { //如果为英文则取1个字节
                    array_push($arr_cont, substr($str, $cind, 1));
                    $cind++;
                } else {
                    array_push($arr_cont, substr($str, $cind, 2));
                    $cind+=2;
                }
            }
        }
        foreach ($arr_cont as &$row) {
            $row = iconv("gb2312", "UTF-8", $row);
        }

        //转换Unicode码
        foreach ($arr_cont as $key => $value) {
            $unicodestr.= $prefix . base_convert(bin2hex(iconv('utf-8', 'UCS-4', $value)), 16, 10) . $postfix;
        }

        return $unicodestr;
    }

    /**
     * 检测用户是否是在微信或者微博内访问
     *
     * @return string
     */
    protected function _checkWiexinEnv() {
        $httpUserAgent = strtolower(empty($_SERVER['HTTP_USER_AGENT']) ? '' : $_SERVER['HTTP_USER_AGENT']);
        if (strpos($httpUserAgent, "micromessenger") !== false) {
            return true;
        }
        return false;
    }
    
    /**
     * 设置登录cookie
     */
    protected function _setSso($sso) {
        if (!$sso) {
            return;
        }
        if (strpos(strrev($_SERVER["HTTP_HOST"]), strrev(".qiu7.net")) !== 0) {
            setcookie('sso', $sso, time() + 5184000, "/", ".qiu7.net"); //30天
        } else {
            setcookie('sso', $sso, time() + 5184000, "/", ".qiu7.net");
        }
        if (!isset($_SESSION)) {
            session_start();
        }
        if (empty($_SESSION["user"])) {
            $result = userBn::analyzeSso($sso);
            if (!$result) {
                exception('用户登录信息验证失败，请刷新页面尝试。还有问题，请联系管理员。', 110020);
            }

            $_SESSION["user"] = $result;
        }
        return true;
    }

}
